package com.jml.web;

import com.jml.annotation.ComponentScan;
import com.jml.annotation.Controller;
import com.jml.annotation.RequestMapping;
import com.jml.config.SpringMvcConfig;
import com.jml.handler.HandlerMethod;
import com.jml.utils.ReflexUtils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;


public class RequestMappingHandlerMapping {
    // 在初始化我们SpringMVC Bean对象、url与方法关联存放到Map集合中
    private Map<String, HandlerMethod> registry = new HashMap<>();

    public void initHandlerMappings() {

        ComponentScan componentScan = SpringMvcConfig.class.getDeclaredAnnotation(ComponentScan.class);
        String springmvcPackage = componentScan.value();
        if (StringUtils.isEmpty(springmvcPackage)) {
            return;
        }
        // 1. 使用java反射机制 查找该包下com.jml.controller 有那些控制类
        Set<Class<?>> classes = ReflexUtils.getClasses(springmvcPackage);
        // 2. 循环遍历每个类 只要有加上
        for (Class<?> classInfo : classes) {
            // 3.判断类上是否有加上我们的控制注解
            Controller controller = classInfo.getDeclaredAnnotation(Controller.class);
            if (controller == null) {
                continue;
            }
            // 4.遍历控制层类中方法是否有加上RequestMapping
            Method[] declaredMethods = classInfo.getDeclaredMethods();
            for (Method methodInfo : declaredMethods) {
                RequestMapping requestMapping = methodInfo.getDeclaredAnnotation(RequestMapping.class);
                if (requestMapping == null) {
                    continue;
                }
                String url = requestMapping.value();
                // 存放到hashMap集合中 key url value: Method
                registry.put(url, new HandlerMethod(newInstance(classInfo), methodInfo));
            }

        }
    }

    private Object newInstance(Class classInfo) {
        try {
            Object value = classInfo.newInstance();
            return value;
        } catch (Exception e) {
            return null;
        }
    }

    public HandlerMethod getHandlerMethod(String url) {
        return registry.get(url);
    }
}
